package com.guinea.generator;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;

import com.guinea.core.utils.StringUtils;

public class MappingClass extends ConfigUtils {
	MappingModule module;
	Config config;

	String name;

	String title;

	String prefix;

	String table;

	String isSequence;

	String isCrud;

	boolean hasRef;

	boolean hasOneToOne;

	boolean hasManyToOne;

	List properties;

	List oneToOne;

	List oneToMany;

	List manyToOne;

	public MappingClass(String name, String title, 
			String prefix, String table, String isSequence, String isCrud) {
		super();
		this.name = StringUtils.capitalize(name);
		this.title = title;
		this.prefix = prefix;
		this.table = table;
		this.isSequence = StringUtils.defaultString(isSequence, "true");
		this.isCrud = StringUtils.defaultString(isCrud, "true");
		if (this.prefix != null) {
			this.prefix = this.prefix.toUpperCase();
		}
		if (this.table == null) {
			this.table = ConfigUtils.camelToTable(name, prefix);
		} else
			this.table = this.table.toUpperCase();

		if (this.prefix != null)
			this.prefix = this.prefix.toUpperCase();
		this.hasRef = false;
		this.hasOneToOne = false;
		this.hasManyToOne = false;
	}

	public String getModulePackage() {
		MappingModule m = getModule();
		return m.getTotalPackage() + "." + m.getModuleName();
	}
	public List getDictDeclares(){
		List result = getDicts();
		List result2 = new ArrayList();
		List typeCache = new ArrayList();
		for (Iterator iter = result.iterator(); iter.hasNext();) {
			DictGroup d = (DictGroup) iter.next();
			if(d.isInGroup()){
				boolean incache = false;
				for (Iterator iterator = typeCache.iterator(); iterator
						.hasNext();) {
					String type = (String) iterator.next();
					if(type.equals(d.getType())){
						incache = true;
						break;
					}
				}
				if(!incache){
					typeCache.add(d.getType());
					String var = StringUtils.replace(d.getType(),",","");
					var = StringUtils.deleteWhitespace(var);
					d.setVar(var);
					result2.add(d);
				}
			}else{
				result2.add(d);
			}
		}
		return result2;
	}
	public List getDictGroups(){
		List result = getDicts();
		List result2 = new ArrayList();
		for (Iterator iter = result.iterator(); iter.hasNext();) {
			DictGroup d = (DictGroup) iter.next();
			if(d.isInGroup()){
				String var = StringUtils.replace(d.getType(),",","");
				var = StringUtils.deleteWhitespace(var);
				d.setVar(var);
				result2.add(d);
			}
		}
		return result2;
	}
	
	public List getDicts(){
		List result = new ArrayList();
		for (Iterator iter = properties.iterator(); iter.hasNext();) {
			MappingProperty p = (MappingProperty) iter.next();
			String d = p.getDict();
			if(d == null) continue;
			if(d.indexOf(":") < 0){
				if(getGroup(result,d) == null)
					result.add(new DictGroup(d,d,false));
			}else{
				String[] g = StringUtils.split(d,':');
				if(g.length != 3) continue;
				DictGroup dictGroup = getGroup(result,g[1]);
				if(dictGroup == null){
					DictGroup dd = new DictGroup(g[0],g[1],true);
					dd.setProperties("\"" + p.getName() + "\"");
					result.add(dd);
				}else{
					DictGroup dg = new DictGroup(dictGroup.getType() + "," + g[0],g[1],true);
					dg.setProperties(dictGroup.getProperties() + ",\"" + p.getName() + "\"");
					result.remove(dictGroup);
					result.add(dg);
				}
			}
		}

		return result;
	}
	
	private DictGroup getGroup(List l,String group){
		for (Iterator iter = l.iterator(); iter.hasNext();) {
			DictGroup g = (DictGroup) iter.next();
			if(group.equals(g.getGroup())) return g;
		}
		return null;
	}

	public String getIsCrud() {
		return isCrud;
	}

	public void setIsCrud(String isCrud) {
		this.isCrud = isCrud;
	}

	public String getIsSequence() {
		return isSequence;
	}

	public void setIsSequence(String isSequence) {
		this.isSequence = isSequence;
	}

	public MappingModule getModule() {
		return module;
	}

	public void setModule(MappingModule module) {
		this.module = module;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPrefix() {
		return prefix;
	}

	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}

	public List getProperties() {
		return properties;
	}

	public void setProperties(List properties) {
		boolean isShowPropertyValid = false;
		for (Iterator iter = properties.iterator(); iter.hasNext();) {
			MappingProperty p = (MappingProperty) iter.next();
			if (p.getShow().equals("true")) {
				isShowPropertyValid = true;
				break;
			}
		}

		if (!isShowPropertyValid && properties.size() > 0) {
			((MappingProperty) properties.get(0)).setShow("true");
		}
		this.properties = properties;
	}

	public String getTable() {
		return table;
	}

	public void setTable(String table) {
		this.table = table;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public List getManyToOne() {
		return manyToOne;
	}

	public void setManyToOne(List manyToOne) {
		if (!this.hasRef && manyToOne != null && manyToOne.size() > 0){
			this.hasRef = true;
			this.hasManyToOne = true;
		}
		this.manyToOne = manyToOne;
	}

	public List getOneToMany() {
		return oneToMany;
	}

	public void setOneToMany(List oneToMany) {
		this.oneToMany = oneToMany;
	}

	public List getOneToOne() {
		return oneToOne;
	}

	public void setOneToOne(List oneToOne) {
		if (!this.hasRef && oneToOne != null && oneToOne.size() > 0){
			for (Iterator iter = oneToOne.iterator(); iter.hasNext();) {
				MappingOneToOne o = (MappingOneToOne) iter.next();
				if(o.inverse.equals("false")){
					this.hasRef = true;
					this.hasOneToOne = true;
					break;
				}
			}
		}
		this.oneToOne = oneToOne;
	}

	public boolean isHasRef() {
		return hasRef;
	}

	public void setHasRef(boolean hasRef) {
		this.hasRef = hasRef;
	}

	public boolean isHasManyToOne() {
		return hasManyToOne;
	}

	public void setHasManyToOne(boolean hasManyToOne) {
		this.hasManyToOne = hasManyToOne;
	}

	public boolean isHasOneToOne() {
		return hasOneToOne;
	}

	public void setHasOneToOne(boolean hasOneToOne) {
		this.hasOneToOne = hasOneToOne;
	}

	public Config getConfig() {
		return config;
	}

	public void setConfig(Config config) {
		this.config = config;
	}

}
